package com.cqhfan.userservice.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqhfan.core.utils.UserContext;
import com.cqhfan.pojo.user.po.Follow;
import com.cqhfan.redis.constants.RedisConstants;
import com.cqhfan.userservice.mapper.FollowMapper;
import com.cqhfan.userservice.service.FollowService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * @author 眭传洪
 * @create 2025-08-02 1:54
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements FollowService {

    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public void addOrRemoveFollowInfo(Long followUserId) {
        Long userId = UserContext.getUser();
        // 查询是否已经关注
        Follow follow = lambdaQuery().eq(Follow::getMyUserId, userId).eq(Follow::getFollowUserId, followUserId).one();
        boolean isFollow = true;
        int incr = 1;
        if (follow == null) {
            // 关注，写入数据库
            follow = new Follow();
            follow.setMyUserId(userId);
            follow.setFollowUserId(followUserId);
            follow.setFollowTime(LocalDateTime.now());
            save(follow);
        } else {
            // 删除关注关系
            removeById(follow.getId());
            isFollow = false;
            incr = -incr;
        }

        // redis添加或移除并发送im消息给被关注，取关不发送
        handleFollowCache(incr, isFollow, userId, followUserId);
    }

    void handleFollowCache(int incr, boolean isFollow, Long userId, Long followUserId) {
        String countKey = RedisConstants.UserProfileInfo.KEY + userId;
        stringRedisTemplate.opsForHash().increment(countKey, RedisConstants.UserProfileInfo.FOLLOW_HASH_KEY, incr);
        countKey = RedisConstants.UserProfileInfo.KEY + followUserId;
        stringRedisTemplate.opsForHash().increment(countKey, RedisConstants.UserProfileInfo.FANS_HASH_KEY, incr);

        // 将关注列表加到set中
        String followKey = RedisConstants.FOLLOW.KEY + userId;
        if (isFollow) {
            stringRedisTemplate.opsForSet().add(followKey, followUserId.toString());
            // TODO 发送即时消息给被关注者
        } else {
            stringRedisTemplate.opsForSet().remove(followKey, followUserId.toString());
        }
    }

    @Override
    public List<Long> listByUserId(Long userId) {
        String key = RedisConstants.FOLLOW.KEY + userId;
        Set<String> members = stringRedisTemplate.opsForSet().members(key);
        if (CollUtil.isEmpty(members)) {
            return Collections.emptyList();
        }
        return members.stream().map(Long::parseLong).toList();
    }

    @Override
    public List<Long> listFriend(Long userId) {
        return getBaseMapper().selectFriends(userId);
    }

    @Override
    public Page<Follow> pageFriend(Page<Follow> page, Long userId) {
        return getBaseMapper().selectFriendPage(page, userId);
    }
}
